<?php
/******************************
 * EQdkp
 * Copyright 2002-2003
 * Licensed under the GNU GPL.  See COPYING for full terms.
 * ------------------
 * parse_log.php
 * Began: Tue December 24 2002
 * 
 * $Id: parse_log.php 541 2008-05-20 06:56:16Z rspeicher $
 * 
 ******************************/
 
define('EQDKP_INC', true);
define('IN_ADMIN', true);
$eqdkp_root_path = './../';
include_once($eqdkp_root_path . 'common.php');

$fv = new Form_Validate;

// Obtain var settings
$parse = ( isset($_REQUEST['parse']) ) ? true : false;

// Start session management
$user->start();
$user->setup();

if ( $parse )
{
    $action = 'parse';
    $fv->is_filled('log');
    
    if ( $fv->is_error() )
    {
        $action = 'display';
    }
}
else
{
    $action = 'display';
}

//
// Processing
//
switch ( $action )
{
    case 'parse':
        $channel_members = '';
        $line = '';
        
        $log_file = explode("\n", $_POST['log']);
        $line_count = sizeof($log_file);
        
        // Go through each line and
        //      - Check for/get a valid member in the /who
        //      - Check if there's a valid date we can use
        //      - Check for/get valid members from /list <channel>
        $log_date = array();
        session_start(); // Hold our array of name => class/level/race
        for ( $i = 0; $i < $line_count; $i++ )
        {
            $line = '';
            if ( strpos($log_file[$i], '<'.$eqdkp->config['guildtag'].'>') )
            {
                $member_name = get_name_from_log($log_file[$i], false);
                if ( trim($member_name) != '')
                {
                    $member_names[] = $member_name;
                }
            }
            
            // Check if there's a usable date/time in this string
            if ( preg_match("/([a-zA-Z]{3}) ([a-zA-Z]{3}) ([0-9]{2}) ([0-9]{2})\:([0-9]{2})\:([0-9]{2}) ([0-9]{4})/", $log_file[$i], $pre_log_date) )
            {
                if ( isset($pre_log_date[0]) )
                {
                    $log_date = $pre_log_date;
                }
                $valid_date_found = true;
            }
             
            // Check if the log contains channel information we can use
            if (preg_match("/Channel (.+)\(([0-9]{1,5})\) members\:/", $log_file[$i], $num_members))
            {
                $first_chan_line = ($i+1);
                $channel_lines = (($num_members[2] % 10) == 0) ? $num_members[2] / 10 : floor($num_members[2] / 10) + 1;
                $last_chan_line = ($i + $channel_lines + 1);
                for ( $j = $first_chan_line; $j < $last_chan_line; $j++ )
                {
                    $line = preg_replace("/\[[A-Za-z]{3} [A-Za-z]{3} [0-9]{2} [0-9]{2}\:[0-9]{2}\:[0-9]{2} [0-9]{4}\]/", '', $log_file[$j]);
                    $line = preg_replace("/[^A-Za-z\,[:space:]]/", '', $line);
                    if ($j != $channel_lines)
                    {
                        $line = str_replace("\n", ', ', $line);
                    }
                    $channel_members .= $line;
                }
            }
        } // for ... log_file
        
        // If there were channel members, join the two arrays
        if ( !empty($channel_members) )
        {
            $channel_members = explode(', ', $channel_members);
            $member_names = array_merge($member_names, $channel_members);
        }
        
        if ( $valid_date_found )
        {
            $date['mo'] = $log_date[2];
            $date['d']  = $log_date[3];
            $date['y']  = $log_date[7];
            $date['h']  = $log_date[4];
            $date['mi'] = $log_date[5];
            $date['s']  = $log_date[6];
        }
        else
        {
            $date['mo'] = date('M');
            $date['d']  = date('d');
            $date['y']  = date('Y');
            $date['h']  = date('h');
            $date['mi'] = date('i');
            $date['s']  = date('s');
        }
        
        // Process the member_names array: replaces spaces, make it unique, sort it and reset it
        if ( (isset($member_names)) && (is_array($member_names)) )
        {
            $name_count = sizeof($member_names);
        }
        else
        {
            $name_count = 0;
            $member_names = array();
        }
        
        for ( $i = 0; $i < $name_count; $i++ )
        {
            $member_names[$i] = str_replace(' ', '', $member_names[$i]);
        }
        $member_names = array_unique($member_names);
        sort($member_names);
        reset($member_names);
        
        $tpl->assign_vars(array(
            'S_STEP1' => false,
            'L_FOUND_MEMBERS' => $user->lang['found_members'],
            'L_LOG_DATE_TIME' => $user->lang['log_date_time'],
            'L_LOG_ADD_DATA' => $user->lang['log_add_data'],
            
            'FOUND_MEMBERS' => implode("\n", $member_names),
            'MO' => M_to_n($date['mo']),
            'D' => $date['d'],
            'Y' => $date['y'],
            'H' => $date['h'],
            'MI' => $date['mi'],
            'S' => $date['s'])
        );
        
        break;
    case 'display':
        $log_columns = ( preg_match("/Mozilla\/4\.[1-9]{1}.+/", $_SERVER['HTTP_USER_AGENT']) ) ? '50' : '90';
        
        $tpl->assign_vars(array(
            'S_STEP1' => true,
            'L_PASTE_LOG' => $user->lang['paste_log'],
            'L_PARSE_LOG' => $user->lang['parse_log'],
            'L_CLOSE_WINDOW' => $user->lang['close_window'],
            
            'LOG_COLS' => $log_columns)
        );
        break;
}

$gen_simple_header = true;
$page_title = sprintf($user->lang['title_prefix'], $eqdkp->config['guildtag'], $eqdkp->config['dkp_name']).': '.$user->lang['parselog_title'];
include_once($eqdkp_root_path . 'includes/page_header.php');

$tpl->set_filenames(array(
    'body' => 'admin/parse_log.html')
);

include_once($eqdkp_root_path . 'includes/page_tail.php');

/**
* Parses a /who GUILD log line to find members of the guild
* 
* @param $log_line String of a log file line
* @param $ignore_role Should we return anonymous/roleplaying members?
*/
function get_name_from_log($log_line, $ignore_role = true)
{
    global $eqdkp, $user;
    
    $name_check = false;
    $role_check = true;
    
    // Date
    $pattern  = "/\[[a-zA-Z]{3} [a-zA-Z]{3} [0-9]{2} [0-9]{2}\:[0-9]{2}\:[0-9]{2} [0-9]{4}\]";
    // AFK
    $pattern .= " (AFK )?";
    // Level / Class
    $pattern .= "\[(ANONYMOUS|([0-9]{1,2})(.+))\]";
    // Name
    $pattern .= " ([A-Za-z]{1,})";
    // Race
    $pattern .= "( \(.*\))?";
    // Guild
    $pattern .= " \<".$eqdkp->config['guildtag']."\>/";
    
    if ( preg_match($pattern, $log_line, $log_parsed) )
    {
        // 0 = date
        // 1 = AFK?
        // 2 = ANONYMOUS | 'XX Class'
        // 3 = Level
        // 4 =  Class
        // 5 = Name
        // 6 =  (Race)
        
        $name = trim($log_parsed[5]);
        $level = trim($log_parsed[3]);
        $class = trim($log_parsed[4]);
        $race = ( isset($log_parsed[6]) ) ? trim(str_replace(')', '', str_replace('(', '', $log_parsed[6]))) : '';
        
        if ( $ignore_role )
        {
            if ( (isset($log_parsed[2])) && ($log_parsed[2] == 'ANONYMOUS') )
            {
                $role_check = false;
            }
        }
     
        if ( (isset($log_parsed[5])) && ($log_parsed[5] != '') )
        {
            $name_check = true;
        }
        
        if ( ($name_check) && ($role_check) )
        {
            $_SESSION[$name] = array(
                'name' => $name,
                'level' => $level,
                'class' => original_class($class),
                'race' => $race);
                
            return $log_parsed[5];
        }
    }
    return false;
}

/**
* Converts the short alphabetic string for a month (M) to a number
* with a leading zero (n) and returns it
* 
* @param $m The short alphabetic month used by EverQuest logs ('Jan')
* @return string n
*/
function M_to_n($m)
{
    switch($m)
    {
        case 'Jan':
            return '01';
            break;
        case 'Feb':
            return '02'; 
            break;
        case 'Mar':
            return '03'; 
            break;
        case 'Apr':
            return '04'; 
            break;
         case 'May': 
            return '05';
            break;
         case 'Jun':
            return '06';
            break;
         case 'Jul':
            return '07'; 
            break;
         case 'Aug': 
            return '08';
            break;
         case 'Sep':
            return '09'; 
            break;
         case 'Oct': 
            return '10';
            break;
         case 'Nov':
            return '11'; 
            break;
         case 'Dec':
            return '12';
            break;
    }
}

/**
* Returns the original EverQuest class that belongs to the level 51+ class name
* 
* @param $class The new class name
* @return mixed Original class name / false
*/
function original_class($class)
{
    $classes = array(
        'Bard' => array('Bard','Minstrel','Troubadour','Virtuoso','Maestro'),
        'Beastlord' => array('Beastlord','Primalist','Animist','Savage Lord','Feral Lord'),
        'Cleric' => array('Cleric','Vicar','Templar','High Priest','Archon'),
        'Druid' => array('Druid','Wanderer','Preserver','Hierophant','Storm Warden'),
        'Enchanter' => array('Enchanter','Illusionist','Beguiler','Phantasmist','Coercer'),
        'Magician' => array('Magician','Elementalist','Conjurer','Arch Mage','Arch Convoker'),
        'Monk' => array('Monk','Disciple','Master','Grandmaster','Transcendent'),
        'Necromancer' => array('Necromancer','Heretic','Defiler','Warlock','Arch Lich'),
        'Paladin' => array('Paladin','Cavalier','Knight','Crusader','Lord Protector'),
        'Ranger' => array('Ranger','Pathfinder','Outrider','Warder','Hunter','Forest Stalker'),
        'Rogue' => array('Rogue','Rake','Blackguard','Assassin','Deceiver'),
        'Shadow Knight' => array('Shadow Knight','Reaver','Revenant','Grave Lord','Dread Lord'),
        'Shaman' => array('Shaman','Mystic','Luminary','Oracle','Prophet'),
        'Warrior' => array('Warrior','Champion','Myrmidon','Warlord','Overlord'),
        'Wizard' => array('Wizard','Channeler','Evoker','Sorcerer','Arcanist')
    );
    
    foreach ( $classes as $k => $v)
    {
        if ( in_array($class, $v) )
        {
            return $k;
        }
    }
    
    return false;
}
?>